<!DOCTYPE html>
<html lang="en">

<head>
  <title>moncler demo</title>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
</head>

<body>
  <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/20.0.0/tween.umd.js"></script>
  <script src="//g.alicdn.com/mtb/lib-video-player/1.1.15/bundle/bundle.js"></script>

  <!-- 首页图片 -->
  <div id="homeImg" style="width:100vw;height:100vh;position: fixed; left: 0px; z-index: 9999;display: none">
    <img src="../res/poster.png" style="width:100%;height:100%" />
  </div>


  <!-- threejs -->
  <div id="container" style="position: fixed; left: 0px; z-index: 1"></div>

  <!-- 视频 -->
  <video class="lib-video vjs-hidden" style="position: fixed; left: 0px; z-index: 0" id="J_Video_Player" poster=""
    muted="false" src="" width="100%">
    <source src="../res/sintel.mp4" type="video/mp4">
    </source>
  </video>

  <button id="sendMessageBtn" style="position: fixed; left: 0px; z-index: 10000; display: none">跳转页面</button>

  <script type="importmap">
    {
        "imports": {
          "three": "../build/three.module.js",
          "three/addons/": "./jsm/"
        }
      }
  </script>

  <script type="module">




    // const temp2 = url.split('?')[1]
    // const pram2 = new URLSearchParams('?' + temp2)
    // const tag = pram2.get('tag')

    // console.log(pram2.get('tag')) // 大数据
    // console.log(temp2)



    import * as THREE from 'three'

    import Stats from 'three/addons/libs/stats.module.js'

    import { GUI } from 'three/addons/libs/lil-gui.module.min.js'
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
    import { Water } from 'three/addons/objects/Water.js'
    import { Sky } from 'three/addons/objects/Sky.js'
    import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
    import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'

    let container, stats
    let camera, scene, renderer
    let controls, water, sun, mesh

    let video, videoTexture, sky
    var BASE_URL = '../'
    let VideoPlayer = lib.videoPlayer;
    let myPlayer = null;
    let model = null;
    let tower = null;
    let yellowFloors = [];
    let texture1, texture2, texture3, texture4, texture1_1, texture2_1, texture3_1, texture4_1

    let enableTouch = false;
    let loadFinish = false;



    myPlayer = VideoPlayer('J_Video_Player', {
      'custom-controls': 'false' //隐藏底部控制栏
    });
    myPlayer.on('video:ended', () => { //监听视频结束事件
      myPlayer.play();
    });



    // 静音
    const closeVolume = (dom) => {
      dom.volume = 0
      dom.muted = true
    }
    // 开启音量
    const openVolume = (dom) => {
      dom.volume = 1
      dom.muted = false
    }

    init()
    animate()

    let sendMessageBtn = document.getElementById('sendMessageBtn')
    sendMessageBtn.onclick = function () {
      if (!loadFinish) return;
      wx.miniProgram.postMessage({ data: 'foo' })
      wx.miniProgram.navigateTo({ url: '/pages/test/test' })
    }



    let homeImg = document.getElementById("homeImg")
    homeImg.style.display = 'block'
    homeImg.onclick = () => {
      if (!loadFinish) return;
      homeImg.style.display = 'none'
      sendMessageBtn.style.display = 'block'
      myPlayer.play();
      panoramaAnimate()
      // touchEvent();
      // touchEnd()
      clickEvent();

    };
    function clickEvent(event) {
      const raycaster = new THREE.Raycaster();
      const mouse = new THREE.Vector2();
      document.addEventListener(
        "mousedown",
        (event) => {
          event.preventDefault();
          // 将鼠标位置转换成归一化设备坐标(-1 到 +1)
          mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
          mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

          // 使用鼠标位置和相机进行射线投射
          raycaster.setFromCamera(mouse, camera);

          // 计算物体和射线的交点
          const intersects = raycaster.intersectObjects(scene.children);

          // 如果有交点
          if (intersects.length > 0) {
            // 获取第一个交点的对象
            console.log(intersects, "intersects");
            const intersection = intersects[0];

            // 你可以访问intersection.object来获取点击的模型对象
            console.log(intersection.object, "yellowFloors模型对象");

            // 你也可以获取点击的坐标等信息
            console.log("Clicked at:", intersection.point);

            // 在这里处理点击模型后的逻辑
            clickModelIsYellow(intersection.object);
          }
        },
        false
      );
    }
    function clickModelIsYellow(modelObject) {
      console.log(modelObject.material, "modelObject.material");
      console.log(yellowFloors, "yellowFloorsccccccccc1111");

      // 让全部得楼变黑
      for (let item of yellowFloors) {
        new TWEEN.Tween(item.material)
          .to({ opacity: 0 }, 800)
          .start()
          .easing(TWEEN.Easing.Sinusoidal.InOut);
      }
      console.log(yellowFloors, "yellowFloorsccccccccc2222");

      console.log(yellowFloors[4].material, "########", modelObject.material);
      // 让当前楼变黄
      const tween1 = new TWEEN.Tween(yellowFloors[4].material)
        .to({ opacity: 1 }, 800)
        .start()
        .easing(TWEEN.Easing.Sinusoidal.InOut); //进入和结束都设置缓动

      // model位置改变
      let x = model.position.x;
      const tween = new TWEEN.Tween(model.position)
        .to({ x: x }, 800)
        .onComplete(() => {
          enableTouch = true;
        })

        .start()
        .easing(TWEEN.Easing.Sinusoidal.InOut); //进入和结束都设置缓动
    };


    window.addEventListener('hashchange', function () {
      console.log('Hash changed to ' + window.location.hash);
      // 定位到第二栋楼
      if (!loadFinish) return;

      let video = myPlayer.getVideoEl()
      closeVolume(video)
      myPlayer.play();

      highLight(1, -16)

    });


    function init() {

      // 渲染器
      initRender()
      // 加载器
      initLoader()
      // 相机
      initCamera()
      // Water
      addWater()
      // Skybox
      addSkyBox()
      // sun
      updateSun()
      // 控制器
      updateControls()


      window.addEventListener('resize', onWindowResize)

      setTimeout(() => {
        loadFinish = true;
        getYellowFloor();
      }, 4000)
    }

    function highLight(index, targetX) {
      //让所有黄色楼边黑
      for (let item of yellowFloors) {
        new TWEEN.Tween(item.material).to({ opacity: 0 }, 500).start()
          .easing(TWEEN.Easing.Sinusoidal.InOut)
      }

      //  让当前楼变黄
      const tween1 = new TWEEN.Tween(yellowFloors[index].material).
        to({ opacity: 1 }, 800).start()
        .easing(TWEEN.Easing.Sinusoidal.InOut)//进入和结束都设置缓动


      // model位置改变
      const tween = new TWEEN.Tween(model.position).
        to({ x: targetX }, 800).onComplete(() => {
          enableTouch = true
        }).start()
        .easing(TWEEN.Easing.Sinusoidal.InOut)//进入和结束都设置缓动
    }

    // 初始化渲染器
    function initRender() {
      scene = new THREE.Scene()
      container = document.getElementById('container')
      renderer = new THREE.WebGLRenderer()
      renderer.setPixelRatio(window.devicePixelRatio)
      renderer.setSize(window.innerWidth, window.innerHeight)
      renderer.toneMapping = THREE.ACESFilmicToneMapping
      renderer.toneMappingExposure = 0.6
      console.log(renderer.domElement, 'renderer.domElement')
      container.appendChild(renderer.domElement)
    }

    // 初始化加载器
    function initLoader() {
      new RGBELoader().load(BASE_URL + 'res/royal_esplanade_1k.hdr', function (texture) {
        texture.mapping = THREE.EquirectangularReflectionMapping
        scene.background = texture
        scene.environment = texture
        render()
        const loader = new GLTFLoader()
        loader.load(BASE_URL + 'res/tower-no.glb', async function (gltf) {
          // 初始化模板节点
          initModel(gltf)
          // 创建模板楼
          initTempTower()
          // 克隆楼 == 黑色
          cloneTower('Genius_City_BG_Tower_1_DEMO', 'Genius_City_BG_Tower_1_DEMO_0_black', 0, -1, true)
          // 克隆楼==视频
          addVideoFloor();
          // 克隆其余的楼
          for (let i = 0; i < 9; i++) {
            let num = Number(i)
            // 黑色楼
            cloneTower('Genius_City_BG_Tower_1_DEMO', 'Genius_City_BG_Tower_1_DEMO' + '_' + (i + 1) + '_black', (i + 1) * 8, -(i + 1), true)
            // 黄色楼
            cloneTower('Genius_City_BG_Tower_1_DEMO', 'Genius_City_BG_Tower_1_DEMO' + '_' + (i + 1), (i + 1) * 8, -(i + 1))
          }
          render()
        })
      })
    }

    // initModel
    async function initModel(gltf) {
      // 黑色建筑
      model = gltf.scene
      model.position.x -= 40

      model.rotation.y += Math.PI
      await renderer.compileAsync(model, camera, scene)
      scene.add(model)
    }

    // 初始化城市
    function initTempTower() {
      texture1 = new THREE.TextureLoader().load(BASE_URL + 'res/BG_Tower_1_Diffuse_1KJ.png')
      texture1.colorSpace = THREE.SRGBColorSpace

      texture2 = new THREE.TextureLoader().load(BASE_URL + 'res/BG_Tower_1_Roughness_1K.png')
      texture2.colorSpace = THREE.SRGBColorSpace

      texture3 = new THREE.TextureLoader().load(BASE_URL + 'res/BG_Tower_1_Normal_1K.png')
      texture3.colorSpace = THREE.SRGBColorSpace

      texture4 = new THREE.TextureLoader().load(BASE_URL + 'res/BG_Tower_1_Emission_1K.png')
      texture4.colorSpace = THREE.SRGBColorSpace

      texture1_1 = new THREE.TextureLoader().load(BASE_URL + 'res/word_BAKE_BaseColor.png')
      texture1_1.colorSpace = THREE.SRGBColorSpace

      texture2_1 = new THREE.TextureLoader().load(BASE_URL + 'res/word_BAKE_Roughness.png')
      texture2_1.colorSpace = THREE.SRGBColorSpace

      texture3_1 = new THREE.TextureLoader().load(BASE_URL + 'res/word_BAKE_Normal.png')
      texture3_1.colorSpace = THREE.SRGBColorSpace

      texture4_1 = new THREE.TextureLoader().load(BASE_URL + 'res/word_BAKE_Emissive.png')
      texture4_1.colorSpace = THREE.SRGBColorSpace

      // 大楼模板
      tower = model.getObjectByName('Genius_City_BG_Tower_1_DEMO')

      var tmpArray = tower.geometry.attributes.uv.array
      for (var i = 0; i < tmpArray.length / 2; i++) {
        tmpArray[i * 2 + 1] = 1.0 - tmpArray[i * 2 + 1]
      }
      tower.geometry.attributes.uv.array = tmpArray
      tower.geometry.attributes.uv.needsUpdate = true
      tower.material.map = texture1
      tower.material.metalnessMap = texture2
      tower.material.roughnessMap = texture2
      tower.material.normalMap = texture3
      tower.material.emissiveMap = texture4
      tower.material.needsUpdate = true

    }

    // 克隆大楼
    function cloneTower(source, name, x, z, isBlack = false) {
      const initX = 8.0
      var tower_clone = model.getObjectByName(source).clone()
      tower_clone.name = name

      // 材质替换就可以
      tower_clone.material = tower.material.clone()
      tower_clone.material.transparent = true;
      tower_clone.material.opacity = 1;

      tower.parent.add(tower_clone)
      tower_clone.position.x -= initX + x

      if (!isBlack) {
        tower_clone.material.map = texture1_1
        tower_clone.material.metalnessMap = texture2_1
        tower_clone.material.roughnessMap = texture2_1
        tower_clone.material.normalMap = texture3_1
        tower_clone.material.emissiveMap = texture4_1
        tower_clone.material.needsUpdate = true
      }
      return tower_clone
    }

    //视频大楼 
    function addVideoFloor() {
      // 第二栋楼
      let addTowerVideo = cloneTower('Genius_City_BG_Tower_1_DEMO', 'Genius_City_BG_Tower_1_DEMO_0', 0, -1)
      setTimeout(() => {
        let material = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide })
        addTowerVideo.material = material
        addTowerVideo.material.transparent = true;
        addTowerVideo.material.opacity = 1;
        let videoTexture = createVideoTexture();
        addTowerVideo.material.map = videoTexture;
        window.addTowerVideo = addTowerVideo
      }, 500)
    }

    // 创建视频纹理
    function createVideoTexture() {
      let video = myPlayer.getVideoEl()
      closeVolume(video)
      myPlayer.play();
      videoTexture = new THREE.VideoTexture(video)
      videoTexture.colorSpace = THREE.SRGBColorSpace
      return videoTexture
    }

    // 获取所有黄色楼
    function getYellowFloor() {
      // 获取所有黄色贴图楼
      yellowFloors = [];
      console.log('scene.children[2]', scene.children[2]);
      for (let i = 0; i < 10; i++) {
        for (let item of scene.children[2].children) {
          if (item.name == `Genius_City_BG_Tower_1_DEMO_${i}`) {
            yellowFloors.push(item)
          }
        }
      }
    }

    // 初始化相机
    function initCamera() {
      camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 20000)
      camera.position.set(0, 0, 1000)
    }

    // 水
    function addWater() {
      const waterGeometry = new THREE.PlaneGeometry(10000, 10000)
      water = new Water(waterGeometry, {
        textureWidth: 512,
        textureHeight: 512,
        waterNormals: new THREE.TextureLoader().load(BASE_URL + 'res/waternormals.jpg', function (texture) {
          texture.wrapS = texture.wrapT = THREE.RepeatWrapping
        }),
        sunDirection: new THREE.Vector3(),
        sunColor: 0xffffff,
        waterColor: 0x001e0f,
        distortionScale: 3.7,
        fog: scene.fog !== undefined,
      })
      water.rotation.x = -Math.PI / 2
      scene.add(water)
    }

    // 天空盒
    function addSkyBox() {
      sky = new Sky()
      sky.scale.setScalar(10000)
      scene.add(sky)

      const skyUniforms = sky.material.uniforms

      skyUniforms['turbidity'].value = 10
      skyUniforms['rayleigh'].value = 2
      skyUniforms['mieCoefficient'].value = 0.005
      skyUniforms['mieDirectionalG'].value = 0.8
    }


    // 太阳光
    function updateSun() {
      sun = new THREE.Vector3()
      const pmremGenerator = new THREE.PMREMGenerator(renderer)
      const parameters = {
        elevation: -3, //时间
        azimuth: -28,
      }
      const sceneEnv = new THREE.Scene()
      const phi = THREE.MathUtils.degToRad(90 - parameters.elevation)
      const theta = THREE.MathUtils.degToRad(parameters.azimuth)
      let renderTarget;

      sun.setFromSphericalCoords(1, phi, theta)

      sky.material.uniforms['sunPosition'].value.copy(sun)
      water.material.uniforms['sunDirection'].value.copy(sun).normalize()

      if (renderTarget !== undefined) renderTarget.dispose()

      sceneEnv.add(sky)
      renderTarget = pmremGenerator.fromScene(sceneEnv)
      scene.add(sky)

      scene.environment = renderTarget.texture
    }

    // 控制器
    function updateControls() {
      controls = new OrbitControls(camera, renderer.domElement)
      controls.enableRotate = false // 禁用旋转
      controls.maxPolarAngle = Math.PI * 0.495
      controls.target.set(0, 5, 0)
      controls.minDistance = 20.0
      controls.maxDistance = 300.0
      controls.update()
    }

    // 获取窗口大小
    function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight
      camera.updateProjectionMatrix()
      renderer.setSize(window.innerWidth, window.innerHeight)
    }

    // 动画
    function animate() {
      requestAnimationFrame(animate)
      render()
      TWEEN.update()
    }

    // 画布渲染
    function render() {
      const time = performance.now() * 0.001
      water.material.uniforms['time'].value += 1.0 / 60.0
      renderer.render(scene, camera)
    }

    // 全景动画
    function panoramaAnimate() {
      // if(tag == 0) {
      new TWEEN.Tween(model.position).
        to({ x: 0 }, 1500).start()
        .easing(TWEEN.Easing.Sinusoidal.InOut)

      console.log(controls.object.position, 'controls.object.position')

      new TWEEN.Tween(controls.object.position).
        to({ z: 40 }, 1500).onComplete(() => {
          enableTouch = true;
        }).start()
        .easing(TWEEN.Easing.Sinusoidal.InOut)

      //让所有黄色楼边黑
      for (let item of yellowFloors) {
        new TWEEN.Tween(item.material).to({ opacity: 0 }, 1500).start()
          .easing(TWEEN.Easing.Sinusoidal.InOut)
      }
    }

    // 触摸事件
    function touchEvent() {
      let startX = 0
      let endX = 0

      container.addEventListener('touchstart', function (event) {
        if (!enableTouch) return;
        event.preventDefault()
        startX = event.touches[0].pageX
        console.log('touchstart_____', startX)
      })

      container.addEventListener('touchend', function (event) {
        if (!enableTouch) return;
        enableTouch = false;
        event.preventDefault()
        endX = event.changedTouches[0].pageX
        let detalX = endX - startX;
        console.log('detalX_______', detalX)
        let step = 0;
        if (Math.abs(detalX) <= 100) {
          step = 0
        } else if (Math.abs(detalX) > 100 && Math.abs(detalX) <= 200) {
          step = 1
        } else if (Math.abs(detalX) > 200 && Math.abs(detalX) <= 300) {
          step = 2
        } else if (Math.abs(detalX) > 300 && Math.abs(detalX) <= 400) {
          step = 3
        } else {
          step = 3
        }

        console.log('step==========', step);


        if (detalX > 0) {
          console.log('左移', model.position.x)
          if (model.position.x >= 0) return enableTouch = true;

          // 根据移动的距离判断哪栋楼该贴黄色贴图
          // console.log(Math.abs(model.position.x) / 8)         
          let currentIndex = (Math.abs(model.position.x) / 8) - step;
          currentIndex = currentIndex < 1 ? 1 : currentIndex


          console.log('currentIndex', currentIndex);


          // 让全部得楼变黑 
          for (let item of yellowFloors) {
            new TWEEN.Tween(item.material).to({ opacity: 0 }, 800).start()
              .easing(TWEEN.Easing.Sinusoidal.InOut)
          }


          // 让当前楼变黄 最大currentIndex是10
          if (currentIndex - 2 >= 0) {
            const tween1 = new TWEEN.Tween(yellowFloors[currentIndex - 2].material).
              to({ opacity: 1 }, 800).start()
              .easing(TWEEN.Easing.Sinusoidal.InOut)//进入和结束都设置缓动
          }

          // 改变model移动距离
          let x = model.position.x + (8 * (step + 1))

          console.log('x', x);

          const tween3 = new TWEEN.Tween(model.position)
            .to({ x: currentIndex == 1 ? 0 : x }, 800).onComplete(() => {
              enableTouch = true;
            }).start()
            .easing(TWEEN.Easing.Sinusoidal.InOut)//进入和结束都设置缓动

        } else {
          console.log('右移', model.position.x)
          if (model.position.x < -72) return enableTouch = true;

          // 根据移动的距离判断哪栋楼该贴黄色贴图
          // console.log(Math.abs(model.position.x) / 8)

          let currentIndex = 0;
          if (Math.abs(model.position.x == 0)) {
            currentIndex = step
          } else {
            currentIndex = (Math.abs(model.position.x) / 8) + step
            currentIndex = currentIndex > 9 ? 9 : currentIndex
          }

          console.log('currentIndex', currentIndex);

          // 让全部得楼变黑 
          for (let item of yellowFloors) {
            new TWEEN.Tween(item.material).to({ opacity: 0 }, 800).start()
              .easing(TWEEN.Easing.Sinusoidal.InOut)
          }


          // 让当前楼变黄
          const tween1 = new TWEEN.Tween(yellowFloors[currentIndex].material).
            to({ opacity: 1 }, 800).start()
            .easing(TWEEN.Easing.Sinusoidal.InOut)//进入和结束都设置缓动


          // model位置改变
          let x = model.position.x - (8 * (step + 1))
          const tween = new TWEEN.Tween(model.position).
            to({ x: currentIndex == 9 ? -80 : x }, 800).onComplete(() => {
              enableTouch = true
            }).start()
            .easing(TWEEN.Easing.Sinusoidal.InOut)//进入和结束都设置缓动
        }
      })
    };

  </script>
</body>

</html>